#include <cstdlib>
#include <utility> // std::forward

template<typename T>
static void Free(T *&p) {
    free(p);
    p = nullptr;
}

template<typename T>
static void Delete(T *&p) {
    delete p;
    p = nullptr;
}

template<typename T>
static void DeleteArray(T *&p) {
    delete []p;
    p = nullptr;
}

template <typename T, size_t N = 1U>
static T *Malloc() {
    return (T*)malloc(N * sizeof(T));
}

template <typename T, typename ... VARGS>
static T *New(VARGS ... vargs) {
    return new T(vargs...);
}

template <typename T, size_t N = 1>
static T *NewArray() {
    return new T[N];
}

static void malloc_and_delete() {
    {
        // malloc and delete
        int *pi = Malloc<int>();
        *pi = 42;
        Delete(pi);
    }
    {
        // malloc and delete[]
        int *pi = Malloc<int>();
        *pi = 42;
        DeleteArray(pi);
    }
    {
        // malloc and free
        int *pi = Malloc<int>();
        *pi = 42;
        Free(pi);
    }
}

static void new_and_free() {
    {
        int *pi = New<int>(42);
        Free(pi);
    }
    {
        int *pi = New<int>(42);
        DeleteArray(pi);
    }
    {
        int *pi = New<int>(42);
        Delete(pi);
    }
}

static void arrays() {
    // 使用不匹配的分配操作符
    int *ints = NewArray<int, 10>();
    Free(ints);
    ints = NewArray<int, 10>();
    Delete(ints);
    ints = NewArray<int, 10>();
    DeleteArray(ints);
}

class Interface {
    int data[10]; // many data
public:
    virtual void foo() {}
};

class Impl : public Interface {
    double d[10]; // more data
public:
    virtual void foo() override {}
};

static void delete_interface() {
    {
        Interface *interface = new Impl;
        interface->foo();
        delete interface;
    }
}

int main()
{
    malloc_and_delete();
    new_and_free();
    arrays();
    delete_interface();
}

